<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      display: flex;
      height: 100vh;
      margin: 0;
      overflow: hidden;
    }

    #left-column,
    #right-container {
      padding: 5px;
      box-sizing: border-box;
    }

    #left-column {
      width: 120px;
      background-color: #f4f4f4;
      overflow-y: auto;
      flex-shrink: 0;
    }

    #right-container {
      flex-grow: 1;
      background-color: #e9e9e9;
      position: relative;
    }

    #left-column>.item {
      margin: 5px;
    }

    .item {
      width: 80px;
      height: 80px;
      background-color: #ccc;
      cursor: move;
      user-select: none;
      position: relative;
    }
  </style>
</head>

<body>
  <div id="left-column"></div>
  <div id="right-container"></div>

  <script>
    const leftColumn = document.getElementById('left-column');
    const rightContainer = document.getElementById('right-container');
    const draggingClassName = "dragging";
    const itemClassName = "item";
    const createFlag = "isCreate"
    const textKey = 'text';
    const dragOffsetXKey = 'dragOffsetX';
    const dragOffsetYKey = 'dragOffsetY';

    for (let i = 0; i < 10; i++) {
      createDraggableItem(leftColumn, `Item ${i + 1}`, i);
    }

    function createDraggableItem(parent, text, index) {
      let item = document.createElement('div');
      if (index === 2) {
        item = document.createElement('img');
        item.src = './fk.png';
      } else if (index === 3) {
        item = document.createElement('img');
        item.src = './sfz.png';
      } else {
        item.textContent = text;
      }
      item.className = itemClassName;
      item.draggable = true;
      parent.appendChild(item);

      makeDraggable(item);
    }

    function makeDraggable(element) {
      element.addEventListener('dragstart', handleDragStart);
      element.addEventListener('dragend', handleDragEnd);
      element.addEventListener('dragover', preventDefaults);
    }

    // 当前被拖拽的元素
    let isDragElement = null;

    function handleDragStart(e) {
      this.style.opacity = '0.4';
      // 将文本内容保存到 dataTransfer 对象中
      e.dataTransfer.setData(textKey, this.textContent);
      // 计算并保存偏移量
      const rect = this.getBoundingClientRect();
      // 将x偏移量保存到 dataTransfer 对象中
      e.dataTransfer.setData(dragOffsetXKey, e.clientX - rect.left);
      // 将y偏移量保存到 dataTransfer 对象中
      e.dataTransfer.setData(dragOffsetYKey, e.clientY - rect.top);

      e.dataTransfer.effectAllowed = "move";
      isDragElement = e.target;
    }

    function handleDragEnd(e) {
      this.style.opacity = '1';
    }

    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
      rightContainer.addEventListener(eventName, preventDefaults, false);
    });

    function preventDefaults(e) {
      e.preventDefault();
      e.stopPropagation();
    }

    rightContainer.addEventListener('drop', handleDrop);

    function getRightContainerBounds() {
      return rightContainer.getBoundingClientRect();
    }

    function handleDrop(e) {
      const text = e.dataTransfer.getData(textKey);
      const dragOffsetX = e.dataTransfer.getData(dragOffsetXKey);
      const dragOffsetY = e.dataTransfer.getData(dragOffsetYKey);
      const offset = getRightContainerBounds();

      const newLeft = e.clientX - offset.left - dragOffsetX;
      const newTop = e.clientY - offset.top - dragOffsetY;

      // 正在拖拽的元素
      const draggingItem = rightContainer.querySelector(`.${draggingClassName}`);
      if (draggingItem) {
        // 已经创建的
        const isCreate = draggingItem.getAttribute(createFlag);
        if (isCreate) {
          // 只修改位置
          draggingItem.style.left = `${newLeft}px`;
          draggingItem.style.top = `${newTop}px`;
          adjustPositionWithinBounds(draggingItem, newLeft, newTop);
          console.log(isDragElement, '被拖拽了');
        } else {
          createItem();
        }
      } else {
        createItem();
      }

      function createItem() {
        if (isDragElement) {
          // 克隆元素
          const newItem = isDragElement.cloneNode(true);
          makeDraggable(newItem);
          newItem.setAttribute('style', '');
          newItem.style.position = 'absolute';
          newItem.style.left = `${newLeft}px`;
          newItem.style.top = `${newTop}px`;
          // 表示已经创建
          newItem.setAttribute(createFlag, true);
          rightContainer.appendChild(newItem);
          adjustPositionWithinBounds(newItem, newLeft, newTop);
          console.log(newItem, '被拖拽到右侧容器');
        }
      }

      isDragElement = null;
    }

    rightContainer.addEventListener('dragstart', (e) => {
      if (e.target && e.target.classList.contains(itemClassName)) {
        e.target.classList.add(draggingClassName);
      }
    });

    rightContainer.addEventListener('dragend', function (e) {
      if (e.target && e.target.classList.contains(itemClassName)) {
        e.target.classList.remove(draggingClassName);
      }
    });


    // 计算拖动位置是否合法
    function adjustPositionWithinBounds(element, intendedLeft, intendedTop) {
      const bounds = getRightContainerBounds();
      const elementRect = element.getBoundingClientRect();

      // 计算元素的新位置，确保它在容器内
      let newLeft = Math.max(0, Math.min(intendedLeft, bounds.width - elementRect.width));
      let newTop = Math.max(0, Math.min(intendedTop, bounds.height - elementRect.height));

      // 设置元素的新位置
      element.style.left = `${newLeft}px`;
      element.style.top = `${newTop}px`;
    }
  </script>
</body>

</html>